package org.lennon.demo.ddd.ticket.service.impl;

import org.lennon.demo.ddd.ticket.aggregate.Ticket;
import org.lennon.demo.ddd.ticket.aggregate.command.TicketCreateCommand;
import org.lennon.demo.ddd.ticket.aggregate.TicketRecord;
import org.lennon.demo.ddd.ticket.aggregate.command.TicketGiveOutCommand;
import org.lennon.demo.ddd.ticket.aggregate.command.TicketReduceCommand;
import org.lennon.demo.ddd.ticket.message.TicketMessageService;
import org.lennon.demo.ddd.ticket.repository.TicketRecordRepository;
import org.lennon.demo.ddd.ticket.repository.TicketRepository;
import org.lennon.demo.ddd.ticket.factory.TicketFactory;
import org.lennon.demo.ddd.ticket.factory.TicketRecordFactory;
import org.lennon.demo.ddd.ticket.service.TicketAppicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

@Service
public class TicketAppicationServiceImpl implements TicketAppicationService {

    @Autowired
    private TicketRepository ticketRepository;

    @Autowired
    private TicketRecordRepository ticketRecordRepository;

    @Autowired
    private TicketMessageService ticketMessageService;

    @Override
    public void create(TicketCreateCommand ticketCreateCommand) {
        Ticket ticket = TicketFactory.create(ticketCreateCommand.getUserId(), 0);
        ticketRepository.save(ticket);
    }

    @Override
    public void giveOut(TicketGiveOutCommand ticketGiveOutCommand) {
        Ticket ticket = ticketRepository.findByUserId(ticketGiveOutCommand.getUserId());
        ticket.giveOut(ticketGiveOutCommand.getAmount());
        ticketRepository.save(ticket);
        TicketRecord ticketRecord = TicketRecordFactory.create(
                ticketGiveOutCommand.getUserId(),
                ticketGiveOutCommand.getExtId(),
                ticketGiveOutCommand.getAmount()
        );
        ticketRecordRepository.save(ticketRecord);
        ticketMessageService.sendTicketAddMessage(ticket);
    }

    @Override
    public void reduce(TicketReduceCommand ticketReduceCommand) {
        Ticket ticket = ticketRepository.findByUserId(ticketReduceCommand.getUserId());
        ticket.reduce(ticketReduceCommand.getAmount());
        ticketRepository.save(ticket);
        TicketRecord ticketRecord = TicketRecordFactory.create(
                ticketReduceCommand.getUserId(),
                ticketReduceCommand.getExtId(),
                ticketReduceCommand.getAmount()
        );
        ticketRecordRepository.save(ticketRecord);
    }

    @Override
    public void batchReduce(Long userId, Set<Long> classIds, Integer singleAmount) {
        Ticket ticket = ticketRepository.findByUserId(userId);
        ticket.reduce(singleAmount * classIds.size());
        ticketRepository.save(ticket);
        List<TicketRecord> ticketRecordList = TicketRecordFactory.create(userId, classIds, singleAmount);
        ticketRecordRepository.save(ticketRecordList);
    }
}
